﻿using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System;


namespace Zwms.Client.CommonUI
{
    //public class SortableBindingList<T> : BindingList<T>
    //{
    //    private bool isSortedCore = true;
    //    private ListSortDirection sortDirectionCore = ListSortDirection.Ascending;
    //    private PropertyDescriptor sortPropertyCore = null;
    //    private string defaultSortItem;

    //    public SortableBindingList() : base() { }

    //    public SortableBindingList(IList<T> list) : base(list) { }

    //    protected override bool SupportsSortingCore
    //    {
    //        get { return true; }
    //    }

    //    protected override bool SupportsSearchingCore
    //    {
    //        get { return true; }
    //    }

    //    protected override bool IsSortedCore
    //    {
    //        get { return isSortedCore; }
    //    }

    //    protected override ListSortDirection SortDirectionCore
    //    {
    //        get { return sortDirectionCore; }
    //    }

    //    protected override PropertyDescriptor SortPropertyCore
    //    {
    //        get { return sortPropertyCore; }
    //    }

    //    protected override int FindCore(PropertyDescriptor prop, object key)
    //    {
    //        for (int i = 0; i < this.Count; i++)
    //        {
    //            if (Equals(prop.GetValue(this), key)) return i;
    //        }
    //        return -1;
    //    }

    //    protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
    //    {
    //        isSortedCore = true;
    //        sortPropertyCore = prop;
    //        sortDirectionCore = direction;
    //        Sort();
    //    }

    //    protected override void RemoveSortCore()
    //    {
    //        if (isSortedCore)
    //        {
    //            isSortedCore = false;
    //            sortPropertyCore = null;
    //            sortDirectionCore = ListSortDirection.Ascending;
    //            Sort();
    //        }
    //    }

    //    public string DefaultSortItem
    //    {
    //        get { return defaultSortItem; }
    //        set
    //        {
    //            if (defaultSortItem != value)
    //            {
    //                defaultSortItem = value;
    //                Sort();
    //            }
    //        }
    //    }

    //    private void Sort()
    //    {
    //        IList<T> list = (this.Items as IList<T>);
    //        list.ToList().Sort(CompareCore);
    //        ResetBindings();
    //    }

    //    private int CompareCore(T o1, T o2)
    //    {
    //        int ret = 0;
    //        if (SortPropertyCore != null)
    //        {
    //            ret = CompareValue(SortPropertyCore.GetValue(o1), SortPropertyCore.GetValue(o2), SortPropertyCore.PropertyType);
    //        }
    //        if (ret == 0 && DefaultSortItem != null)
    //        {
    //            PropertyInfo property = typeof(T).GetProperty(DefaultSortItem, BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.IgnoreCase, null, null, new Type[0], null);
    //            if (property != null)
    //            {
    //                ret = CompareValue(property.GetValue(o1, null), property.GetValue(o2, null), property.PropertyType);
    //            }
    //        }
    //        if (SortDirectionCore == ListSortDirection.Descending) ret = -ret;
    //        return ret;
    //    }

    //    private static int CompareValue(object o1, object o2, Type type)
    //    {
    //        //这里改成自己定义的比较 
    //        if (o1 == null) return o2 == null ? 0 : -1;
    //        else if (o2 == null) return 1;
    //        else if (type.IsPrimitive || type.IsEnum) return Convert.ToDouble(o1).CompareTo(Convert.ToDouble(o2));
    //        else if (type == typeof(DateTime)) return Convert.ToDateTime(o1).CompareTo(o2);
    //        else return String.Compare(o1.ToString().Trim(), o2.ToString().Trim());
    //    }
    //}

    public class ObjectPropertyCompare<T> : IComparer<T>
    {
        private PropertyDescriptor property; 
        private ListSortDirection direction;
        public ObjectPropertyCompare(PropertyDescriptor property, ListSortDirection direction) 
        {
            this.property = property; 
            this.direction = direction; 
        }

        public int Compare(T x, T y) 
        {
            object xValue = x.GetType().GetProperty(property.Name).GetValue(x, null); 
            object yValue = y.GetType().GetProperty(property.Name).GetValue(y, null); 
            int returnValue; if (xValue is IComparable) 
            { 
                returnValue = ((IComparable)xValue).CompareTo(yValue); 
            } 
            else if (xValue.Equals(yValue)) 
            { 
                returnValue = 0; 
            } 
            else 
            { 
                returnValue = xValue.ToString().CompareTo(yValue.ToString()); 
            } 
            
            if (direction == ListSortDirection.Ascending) 
            { 
                return returnValue; 
            } 
            else 
            { 
                return returnValue * -1; 
            } 
        }
    }

    public class BindingCollection<T> : BindingList<T>
    {
        private bool isSorted;
        private PropertyDescriptor sortProperty; 
        private ListSortDirection sortDirection;
        public BindingCollection() : base() { }
        public BindingCollection(IList<T> list) : base(list) { }
        protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction) 
        {
            List<T> items = this.Items as List<T>; 
            if (items != null) 
            { 
                ObjectPropertyCompare<T> pc = new ObjectPropertyCompare<T>(property, direction); 
                items.Sort(pc); isSorted = true; 
            } 
            else 
            { 
                isSorted = false; 
            } 
            sortProperty = property; 
            sortDirection = direction; 
            this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); 
        }
        protected override bool IsSortedCore { get { return isSorted; } }
        protected override bool SupportsSortingCore { get { return true; } }
        protected override ListSortDirection SortDirectionCore { get { return sortDirection; } }
        protected override PropertyDescriptor SortPropertyCore { get { return sortProperty; } }
        protected override void RemoveSortCore() { isSorted = false; this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); }
    }
}
